home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Tools - Objects / MacApp / MacApp 2.0 CD Release / MacApp 2.0 (Many Libraries) / Tools / UMPWTool.p < prev   
Encoding:
Text File  |  1990-03-27  |  10.5 KB  |  453 lines  |  [TEXT/MPS ]

  1. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n+]}
  2.  
  3. {------------------------------------------------------------------------------
  4. Simple framework for an MPW tool.
  5.  
  6. NOTE - tools cannot currently be built with -debug… Sorry!
  7. ------------------------------------------------------------------------------}
  8. UNIT UMPWTool;
  9.  
  10.     INTERFACE
  11.  
  12.         USES
  13.             { • MacApp }
  14.             UMacApp,
  15.  
  16.             { • Building Blocks }
  17.  
  18.             { • Required for this unit's interface }
  19.             UAssociation,
  20.  
  21.             { • Implementation use }
  22.             CursorCtl, Signal, PasLibIntf, IntEnv, ErrMgr, Events, OSUtils, Memory, Resources, Fonts;
  23.  
  24.         CONST
  25.             Version             = '1.0';                { Current version}
  26.             kErrorMarker        = '### ';
  27.             
  28.             { Keyword IDs.  Negative numbers reserved for the framework }
  29.             kwP = -1;
  30.             kwNoP = -2;
  31.             kwT = -3;
  32.             kwNoT = -4;
  33.             kwHelp = -5;
  34.  
  35.         TYPE
  36.             TMPWTool            = OBJECT (TObject)
  37.                 fKeyWordList:        TAssociation;        { keywords to this command }
  38.                 fProgName:            Str255;             { Program's file name}
  39.                 fInterrupted:        Boolean;            { True ==> interrupted (Cmd "." pressed)}
  40.                 fCursorCount:        integer;            { for our spinning cursor}
  41.                 fRetCode:            (RC_Normal, RC_ParmErrs, RC_DontMatch, RC_Abort); {Return codes}
  42.                 fProgress:            Boolean;            { true for progress request }
  43.                 fTime:                Boolean;            { true for elapsed time request }
  44.                 fStartTicks:        Longint;            { tickcount at start of tool }
  45.                 fStartDateTime:     Longint;            { Date/Time at start of tool }
  46.                 fArgVIndex:         integer;
  47.  
  48.                 PROCEDURE TMPWTool.ITool;
  49.                 PROCEDURE TMPWTool.InstallKeyWord(keyword: Str255; kw: Integer);
  50.                 FUNCTION TMPWTool.LookupKeyword(keyword: Str255; var kw: Integer): BOOLEAN;
  51.                 PROCEDURE TMPWTool.InstallKeyWords;
  52.                 PROCEDURE TMPWTool.DoProcessFileArg(arg: Str255);
  53.                 PROCEDURE TMPWTool.DoProcessOptionArg(kw: integer);
  54.                 PROCEDURE TMPWTool.DoShowUsage;
  55.                 PROCEDURE TMPWTool.DoStartProgress;
  56.                 PROCEDURE TMPWTool.DoToolAction;
  57.                 FUNCTION TMPWTool.GetNextArg: Str255;
  58.                 PROCEDURE TMPWTool.ProcessArg(arg: Str255);
  59.                 PROCEDURE TMPWTool.Run;
  60.                 PROCEDURE TMPWTool.Stop(msg: Str255);
  61.                 PROCEDURE TMPWTool.SyntaxError(suffix: Str255);
  62.                 END;
  63.  
  64.         PROCEDURE InitUMPWTool;
  65.  
  66.         {$IFC qTrace}
  67.         {$Push} {$%+}
  68.  
  69.         PROCEDURE %_BP;
  70.  
  71.         PROCEDURE %_EP;
  72.  
  73.         PROCEDURE %_EX;
  74.         {$Pop}
  75.         {$ENDC}
  76.  
  77.         VAR
  78.             gTool:                TMPWTool;                { The tool }
  79.             gProgName:            Str255;                 { Program's file name}
  80.  
  81.     IMPLEMENTATION
  82.  
  83. {--------------------------------------------------------------------------------------------------}
  84.  
  85.         {$IFC qTrace}
  86.         {$Push} {$%+}
  87.         {$S Main}
  88.  
  89.         PROCEDURE %_BP;
  90.  
  91.             BEGIN
  92.             END;
  93.         {$S Main}
  94.  
  95.         PROCEDURE %_EP;
  96.  
  97.             BEGIN
  98.             END;
  99.         {$S Main}
  100.  
  101.         PROCEDURE %_EX;
  102.  
  103.             BEGIN
  104.             END;
  105.         {$Pop}
  106.         {$ENDC}
  107.  
  108. {--------------------------------------------------------------------------------------------------}
  109.  
  110.         {$S TInit}
  111.  
  112.         PROCEDURE InitUMPWTool;
  113.  
  114.             BEGIN
  115.             { Do Tool related initialization }
  116.             InitGraf(@thePort);
  117.             SetFScaleDisable(true);                     { per chapter in MPW guide on tools }
  118.  
  119.             InitCursorCtl(NIL);
  120.             RotateCursor(0);
  121.  
  122.             InitErrMgr('', '', false);
  123.  
  124.             gProgName := ArgV^[0]^;
  125.  
  126.             DefineConfiguration(gConfiguration);
  127.  
  128.             SetRGBColor(gRGBBlack, 0, 0, 0);
  129.             SetRGBColor(gRGBWhite, $FFFF, $FFFF, $FFFF);
  130.             gStrippedAddress := StripAddress(Ptr( - 1));
  131.             gCursorRgn := NewRgn;
  132.         
  133.             gBoolString[true] := 'TRUE';
  134.             gBoolString[FALSE] := 'FALSE';
  135.             gDeadStripSuppression := FALSE;
  136.             gCreateWithTemplates := gDeadStripSuppression;        { for compatibility with Dave W. class notes
  137.                                                                  }
  138.             { The refnum where the application's resources should be found }
  139.             gApplicationRefNum := CurResFile;
  140.         
  141.             gToolBoxInitialized := true;
  142.  
  143.             { the main procedure is always compiled with universal code so, the FPU must be reset before it
  144.             is used.  We could get spurious crashes or worse.
  145.             
  146.             Remember: 2+2=4… every time!
  147.             }
  148.         
  149.             InitUPatch;
  150.                     
  151.             { the following set up is necessary to call CleanupMacApp }
  152.             gApplication := NIL;
  153.                 
  154.             FailNil(gCursorRgn);
  155.         
  156.  
  157.             { Do Object related initialization }
  158.             InitUObject;
  159.  
  160.             END;
  161.  
  162. {--------------------------------------------------------------------------------------------------}
  163.         {$S TRes}
  164.  
  165.         PROCEDURE Intr;
  166.  
  167.             BEGIN
  168.             gTool.fInterrupted := true;                 {we test this switch periodically}
  169.             END;
  170.  
  171. {--------------------------------------------------------------------------------------------------}
  172.         {$S TRes}
  173.  
  174.         PROCEDURE TMPWTool.Stop(msg: Str255);
  175.  
  176.             BEGIN
  177.             IF Length(msg) > 0 THEN
  178.                 BEGIN
  179.                 PLFlush(Output);
  180.                 WriteLn(Diagnostic);
  181.                 WriteLn(Diagnostic, msg);
  182.                 END;
  183.  
  184.             IF fInterrupted THEN
  185.                 IEexit( - 9);
  186.  { don't worry about closing the files we opened.  The Shell
  187.   will do so if appropriate.}
  188.             IEexit(Ord(fRetCode));                        {exit, returning the appropriate status
  189.                                                          code}
  190.             END;
  191.  
  192. {--------------------------------------------------------------------------------------------------}
  193.         {$S TInit}
  194.  
  195.         PROCEDURE TMPWTool.SyntaxError(suffix: Str255);
  196.  
  197.             VAR
  198.                 aStr: Str255;
  199.  
  200.             BEGIN
  201.             aStr := fProgName;
  202.             PLFlush(Output);
  203.             WriteLn(Diagnostic, kErrorMarker, 'Bad Parameter: ', suffix);
  204.             WriteLn(Diagnostic, kErrorMarker, aStr, '<invalid option>');
  205.             Stop('');
  206.             END;
  207.  
  208. {--------------------------------------------------------------------------------------------------}
  209.         {$S TInit}
  210.  
  211.         PROCEDURE TMPWTool.DoShowUsage;
  212.  
  213.             VAR
  214.                 aStr: Str255;
  215.  
  216.             BEGIN
  217.             aStr := fProgName;
  218.             WriteLn(Diagnostic, '# Usage: ', aStr, ' [-p]');
  219.             END;
  220.  
  221. {--------------------------------------------------------------------------------------------------}
  222.         {$S TInit}
  223.  
  224.         FUNCTION TMPWTool.GetNextArg: Str255;
  225.  
  226.             BEGIN
  227.             fArgVIndex := fArgVIndex + 1;
  228.             IF fArgVIndex > ArgC THEN
  229.                 Stop('Not enough arguments');
  230.             GetNextArg := ArgV^[fArgVIndex]^;
  231.             END;
  232.  
  233. {--------------------------------------------------------------------------------------------------}
  234.         {$S TInit}
  235.  
  236.         PROCEDURE TMPWTool.InstallKeyWords;
  237.  
  238.             BEGIN
  239.             InstallKeyWord('P', kwP);
  240.             InstallKeyWord('NoP', kwNoP);
  241.             InstallKeyWord('T', kwT);
  242.             InstallKeyWord('NoT', kwNoT);
  243.             InstallKeyWord('Help', kwHelp);
  244.             END;
  245.  
  246. {--------------------------------------------------------------------------------------------------}
  247.         {$S TInit}
  248.  
  249.         PROCEDURE TMPWTool.InstallKeyWord(keyword: Str255; kw: Integer);
  250.             var
  251.                 value:    Str255;
  252.  
  253.             BEGIN
  254.             UprStr255(keyword);
  255.             value[0] := chr(2);
  256.             value[1] := chr(BSR(Band(kw, $FF00), 8));
  257.             value[2] := chr(Band(kw, $00FF));
  258.             fKeyWordList.InsertEntry(keyword, value);
  259.             END;
  260.  
  261. {--------------------------------------------------------------------------------------------------}
  262.         {$S TInit}
  263.  
  264.         FUNCTION TMPWTool.LookupKeyword(keyword: Str255; var kw: Integer): BOOLEAN;
  265.             var
  266.                 value:    Str255;
  267.  
  268.             BEGIN
  269.             UprStr255(keyword);
  270.             if fKeyWordList.ValueAt(keyword, value) then
  271.                 begin
  272.                 LookupKeyword := true;
  273.                 kw := BOR(BSL(ord4(value[1]), 8), ord(value[2]));
  274.                 end
  275.             else
  276.                 LookupKeyword := false;
  277.             END;
  278.  
  279. {--------------------------------------------------------------------------------------------------}
  280.         {$S TInit}
  281.  
  282.         PROCEDURE TMPWTool.ProcessArg(arg: Str255);
  283.             var
  284.                 akw: integer;
  285.  
  286.             BEGIN
  287.             IF arg[1] <> '-' THEN
  288.                 DoProcessFileArg(arg)
  289.             ELSE
  290.                 begin
  291.                 if LookupKeyWord(copy(arg, 2, Length(arg) - 1), akw) then
  292.                     DoProcessOptionArg(akw)
  293.                 else
  294.                     SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid option>'));
  295.                 end;
  296.             END;
  297.  
  298. {--------------------------------------------------------------------------------------------------}
  299.         {$S TInit}
  300.  
  301.         PROCEDURE TMPWTool.DoProcessFileArg(arg: Str255);
  302.  
  303.             BEGIN
  304.             SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid option>'));
  305.             END;
  306.  
  307. {--------------------------------------------------------------------------------------------------}
  308.         {$S TInit}
  309.  
  310.         PROCEDURE TMPWTool.DoProcessOptionArg(kw: integer);
  311.  
  312.             BEGIN
  313.             case kw of
  314.             kwP:
  315.                 fProgress := true;
  316.             kwNoP:
  317.                 fProgress := false;
  318.             kwT:
  319.                 fTime := true;
  320.             kwNoT:
  321.                 fTime := false;
  322.             kwHelp:
  323.                 BEGIN
  324.                 DoShowUsage;
  325.                 fRetCode := RC_Normal;
  326.                 Stop('');
  327.                 END;
  328.             otherwise
  329.                 SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid option>'));
  330.             end;
  331.             END;
  332.  
  333. {--------------------------------------------------------------------------------------------------}
  334.         {$S TInit}
  335.  
  336.         PROCEDURE TMPWTool.DoStartProgress;
  337.  
  338.             VAR
  339.                 aStr: Str255;
  340.  
  341.             BEGIN
  342.             aStr := fProgName;
  343.             WriteLn(Diagnostic);
  344.             WriteLn(Diagnostic, aStr, '  (Ver ', Version, ') ');
  345.             WriteLn(Diagnostic);
  346.             WriteLn(Diagnostic);
  347.             END;
  348.  
  349. {--------------------------------------------------------------------------------------------------}
  350.         {$S TInit}
  351.  
  352.         PROCEDURE TMPWTool.ITool;
  353.  
  354.             VAR
  355.                 holdIndex:            integer;
  356.                 prevSig:            SignalHandler;
  357.                 arg:                Str255;
  358.                 theDateTime:        Longint;
  359.                 anAssociation:        TAssociation;
  360.  
  361.             BEGIN
  362.             fStartTicks := TickCount;
  363.             GetDateTime(theDateTime);
  364.             fStartDateTime := theDateTime;
  365.  
  366.             fRetCode := RC_Normal;
  367.  
  368.             fInterrupted := false;                        {becomes True when interrupted}
  369.             fCursorCount := 0;                            { prepare to spin that cursor}
  370.             SpinCursor(1);
  371.             prevSig := IEsignal(SIGINT, @Intr);
  372.  
  373.             fProgress := false;
  374.             fTime := false;
  375.             fProgName := ArgV^[0]^;
  376.             gProgName := fProgName;
  377.             fRetCode := RC_ParmErrs;
  378.  
  379.             IF fInterrupted THEN
  380.                 Stop('');
  381.  
  382.             New(anAssociation);
  383.             FailNil(anAssociation);
  384.             anAssociation.IAssociation;
  385.             fKeyWordList := anAssociation;
  386.  
  387.             InstallKeyWords;
  388.             END;
  389.  
  390. {--------------------------------------------------------------------------------------------------}
  391.         {$S TRes}
  392.  
  393.         PROCEDURE TMPWTool.Run;
  394.  
  395.             VAR
  396.                 fi:                 FailInfo;
  397.  
  398.             LABEL 1000;
  399.  
  400.             PROCEDURE HdlFailure(error: integer; message: Longint);
  401.  
  402.                 VAR
  403.                     theErr:             OSErr;
  404.                     theText:            Str255;
  405.  
  406.                 BEGIN
  407.                 theErr := error;
  408.                 IF theErr <> noErr THEN
  409.                     BEGIN
  410.                     GetSysErrText(theErr, @theText);
  411.                     WriteLn(Diagnostic, kErrorMarker, gProgName, ': ', theText);
  412.                     fRetCode := RC_Abort;
  413.                     END;
  414.                 GOTO 1000;
  415.                 END;
  416.  
  417.             BEGIN
  418.             CatchFailures(fi, HdlFailure);
  419.             fArgVIndex := 1;
  420.             WHILE fArgVIndex < ArgC DO                    {ArgC is the number of args plus one}
  421.                 BEGIN
  422.                 fCursorCount := fCursorCount + 1;
  423.                 RotateCursor(fCursorCount);
  424.                 ProcessArg(ArgV^[fArgVIndex]^);
  425.                 fArgVIndex := fArgVIndex + 1;
  426.                 END;
  427.             UnloadSeg(@InitUMPWTool);
  428.             fRetCode := RC_Normal;
  429.  
  430.             IF fProgress THEN
  431.                 DoStartProgress;
  432.             DoToolAction;
  433.             IF fTime THEN
  434.                 WriteLn(Diagnostic, 'Elapsed time: ', (TickCount - fStartTicks) / 60: 1:
  435.                         2, ' seconds');
  436.             Success(fi);
  437.         1000:
  438.             IEexit(Ord(fRetCode));
  439.             END;
  440. {--------------------------------------------------------------------------------------------------}
  441.         {$S TRes}
  442.  
  443.         PROCEDURE TMPWTool.DoToolAction;
  444.             VAR
  445.                 aStr: Str255;
  446.  
  447.             BEGIN
  448.             aStr := fProgName;
  449.             WriteLn(Diagnostic, kErrorMarker, aStr,
  450.                     ': Forgot to override the default tool action');
  451.             END;
  452. END.
  453.